package com.lizemin.jingdongmall.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lizemin.jingdongmall.entity.Stock;
import com.lizemin.jingdongmall.mapper.StockMapper;
import com.lizemin.jingdongmall.service.IStockService;
import com.lizemin.jingdongmall.service.RedisLockService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lizemin
 * @since 2025-03-26
 */
@Service
@Slf4j
public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements IStockService {

    private final Object lock = new Object();

    @Autowired
    private RedisLockService lockService;

    @Override
    public void buyIphone() {
        // 查询iphone的库存
        Stock stock = baseMapper.selectById(1);
        if (stock.getCount() <= 0) {
            throw new RuntimeException("商品卖完啦，请过两天再来看看");
        }
        // 模拟其他耗时的操作，比如创建订单
        try {
            TimeUnit.SECONDS.sleep(1);
            log.info("订单创建成功");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        int rows = baseMapper.updateStorage();
        if (rows == 0) {
            throw new RuntimeException("库存已被更新，请重试");
        }
        log.info("库存扣减成功");
    }

    @Override
    public void buyIphone2() {
        synchronized (lock) {
            // 查询iphone的库存
            Stock stock = baseMapper.selectById(1);
            if (stock.getCount() <= 0) {
                throw new RuntimeException("商品卖完啦，请过两天再来看看");
            }
            // 模拟其他耗时的操作，比如创建订单
            try {
                TimeUnit.SECONDS.sleep(1);
                log.info("订单创建成功");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            int rows = baseMapper.updateStorage();
            if (rows == 0) {
                throw new RuntimeException("库存已被更新，请重试");
            }
            log.info("库存扣减成功");
        }
    }

    @Override
    public void buyIphone3() {
        // 查询iphone的库存
        Stock stock = baseMapper.selectById(1);
        if (stock.getCount() <= 0) {
            throw new RuntimeException("商品卖完啦，请过两天再来看看");
        }
        // 模拟其他耗时的操作，比如创建订单
        try {
            TimeUnit.SECONDS.sleep(1);
            log.info("订单创建成功");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        int rows = baseMapper.updateStorage2(stock.getVersion());
        if (rows == 0) {
            throw new RuntimeException("库存已被更新，请重试");
        }
        log.info("库存扣减成功");
    }

    @Override
    public void buyIphone4() {
        String version = UUID.randomUUID().toString();
        String lockKey = "stock:1";
        boolean success = lockService.tryLock(lockKey, version, 30, TimeUnit.MINUTES);
        if (!success) {
            throw new RuntimeException("没有获取到分布式锁，请稍后再试");
        }else {
            log.info("成功获取到分布式锁");
        }
        // 查询iphone的库存
        Stock stock = baseMapper.selectById(1);
        if (stock.getCount() <= 0) {
            lockService.releaseLock(lockKey, version);
            throw new RuntimeException("商品卖完啦，请过两天再来看看");
        }
        // 模拟其他耗时的操作，比如创建订单
        try {
            TimeUnit.SECONDS.sleep(1);
            log.info("订单创建成功");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        int rows = baseMapper.updateStorage();
        if (rows == 0) {
            throw new RuntimeException("库存已被更新，请重试");
        }
        log.info("库存扣减成功");
        boolean result = lockService.releaseLock(lockKey, version);
        if (result) {
            log.info("释放锁成功");
        }else {
            throw new RuntimeException("释放锁失败，请稍后再试");
        }
    }


}
